package com.pureut.system.service.impl;

import com.alibaba.fastjson.JSONArray;
import com.pureut.common.core.utils.StringUtils;
import com.pureut.common.datascope.annotation.DataScope;
import com.pureut.common.security.utils.DictUtils;
import com.pureut.common.security.utils.SecurityUtils;
import com.pureut.system.api.domain.SysDictData;
import com.pureut.system.domain.SysAppConfig;
import com.pureut.system.domain.SysAppConfigNode;
import com.pureut.system.domain.SysTheAlarm;
import com.pureut.system.domain.dto.SysAppConfigDto;
import com.pureut.system.domain.dto.SysAppConfigNodeDto;
import com.pureut.system.domain.dto.SysAuditHistoryDto;
import com.pureut.system.domain.dto.SysTheDropDto;
import com.pureut.system.domain.vo.SysAppConfigVo;
import com.pureut.system.domain.vo.SysAuditHistoryVo;
import com.pureut.system.mapper.SysAppConfigMapper;
import com.pureut.system.mapper.SysAppConfigNodeMapper;
import com.pureut.system.mapper.SysAuditHistoryMapper;
import com.pureut.system.mapper.SysTheAlarmMapper;
import com.pureut.system.service.ISysAppConfigService;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * @Description 审核配置实现类
 * @Param
 * @Date 22-12-08
 * @Author hl
 **/
@Service
public class SysAppConfigServiceImpl implements ISysAppConfigService {
    @Resource
    private SysAppConfigMapper sysAppConfigMapper;

    @Resource
    private SysAppConfigNodeMapper sysAppConfigNodeMapper;

    @Resource
    private SysTheAlarmMapper sysTheAlarmMapper;

    @Resource
    private SysUserServiceImpl sysUserServiceImpl;

    @Resource
    private SysRoleServiceImpl sysRoleServiceImpl;

    @Resource
    private SysMenuServiceImpl sysMenuServiceImpl;

    @Resource
    private SysAuditHistoryMapper sysAuditHistoryMapper;


    //@Value("${rocketmq.name-server}")
    // private String mqServer;

    //@Value("${producer.group}")
    // private String mqGroup;

    //@Value("${producer.send-message-timeout}")
    //private int mqTimeOut;

    /**
     * 查询审核信息
     *
     * @param sysAppconfigVo 审核信息
     * @return 审核信息集合
     */
    @Override
    @DataScope(deptAlias = "t1")
    public List<SysAppConfigDto> selectAppConfigList(SysAppConfigVo sysAppconfigVo) {
        return sysAppConfigMapper.selectAppConfigList(sysAppconfigVo);
    }

    /**
     * 新增审核信息
     *
     * @param sysAppConfig 审核信息
     * @return 审核信息集合
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public int insertAppConfig(SysAppConfig sysAppConfig) throws Exception {
        int in = sysAppConfigMapper.appCheckUniqueness(sysAppConfig.getAppconfigCode());
        if (in > 0) {
            throw new SQLException("配置编码不能重复");
        }
        sysAppConfig.setDeptId(SecurityUtils.getDeptId());
        List<String> appList = sysAppConfig.getAppconfigButtonIds();
        String sy = "";
        for (String code :
                appList) {
            sy += code + ",";
        }
        sy = sy.substring(0, sy.length() - 1);
        sysAppConfig.setButtonIds(sy);
        int ins = sysAppConfigMapper.insertAppconfig(sysAppConfig);
        if (ins == 0) {
            throw new SQLException("抛出异常");
        }
        return theNodeConfig(sysAppConfig);
    }

    /**
     * 删除审核信息
     *
     * @param appconfigId 审核Id
     * @return 审核信息
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public int deleteSysAppconfig(String appconfigId) throws Exception {
        String[] arr = appconfigId.split(",");
        int in = sysAppConfigMapper.deleteSysAppconfigBy(arr);
        if (in == 0) {
            throw new SQLException("抛出异常");
        }
        return in;
    }


    /**
     * 查询审核信息
     *
     * @param appId 审核Id
     * @return 审核信息
     */
    @Override
    public SysAppConfigDto getAppconfigInfo(long appId) {
        SysAppConfigVo sysAppconfigVo = new SysAppConfigVo();
        sysAppconfigVo.setAppconfigId(appId);
        List<SysAppConfigDto> list = sysAppConfigMapper.selectAppConfigList(sysAppconfigVo);
        SysAppConfigDto sysAppconfigDto = list.get(0);
        List<SysAppConfigNodeDto> nodeList = sysAppConfigNodeMapper.getAppNodeInfo(sysAppconfigDto.getAppconfigId());
        List<SysDictData> dictList = DictUtils.getDictCache("sys_of_nodes");
        List<SysDictData> dictList2 = DictUtils.getDictCache("sys_alarm_mode");
        List<SysDictData> dictList3 = DictUtils.getDictCache("sys_alarm_unit");
        List<SysDictData> dictList4 = DictUtils.getDictCache("sys_alarm_nexus");
        Map<String, String> actualMap = dictList.stream().collect(Collectors.toMap(SysDictData::getDictValue, SysDictData::getDictLabel));
        Map<String, String> actualMap2 = dictList2.stream().collect(Collectors.toMap(SysDictData::getDictValue, SysDictData::getDictLabel));
        Map<String, String> actualMap3 = dictList3.stream().collect(Collectors.toMap(SysDictData::getDictValue, SysDictData::getDictLabel));
        Map<String, String> actualMap4 = dictList4.stream().collect(Collectors.toMap(SysDictData::getDictValue, SysDictData::getDictLabel));
        for (SysAppConfigNodeDto sy :
                nodeList) {
            //取出用户id
            String userId = sy.getNodeUserId();
            String userName = sysUserServiceImpl.selectUserNameService(userId);
            String[] nameS = userName.split(",");
            String[] userIdS = userId.split(",");
            List<SysTheDropDto> listThe = new ArrayList<SysTheDropDto>();
            for (int i = 0; i < nameS.length; i++) {
                SysTheDropDto st = new SysTheDropDto();
                st.setLabel(nameS[i]);
                st.setValue(userIdS[i]);
                listThe.add(st);
            }
            sy.setNodeUser(listThe);
            String roleId = sy.getNodeRoleId();
            String roleName = sysRoleServiceImpl.selectRoleNameService(roleId);
            sy.setNodeTheOrderDict(actualMap.get(String.valueOf(sy.getNodeTheOrder())));
            List<SysTheAlarm> theAlarmList = sysTheAlarmMapper.selectSysTheAlarmList(sy.getNodeId(), 5);
            if (!StringUtils.isEmpty(roleName)) {
                String[] roleIdS = roleId.split(",");
                String[] roleNameS = roleName.split(",");
                List<SysTheDropDto> listThe2 = new ArrayList<SysTheDropDto>();
                for (int j = 0; j < roleIdS.length; j++) {
                    SysTheDropDto st = new SysTheDropDto();
                    st.setValue(roleIdS[j]);
                    st.setLabel(roleNameS[j]);
                    listThe2.add(st);
                }
                sy.setNodeRole(listThe2);
                sy.setUserAndRole(userName + "," + roleName);
            }
            for (SysTheAlarm sysTheAlarm :
                    theAlarmList) {
                sysTheAlarm.setAlarmWayDict(actualMap2.get(sysTheAlarm.getAlarmWay()));
                sysTheAlarm.setAlarmUnitDict(actualMap3.get(sysTheAlarm.getAlarmUnit()));
                sysTheAlarm.setAlarmNexusDict(actualMap4.get(sysTheAlarm.getAlarmNexus()));
            }

            sy.setTheAlarmCode(theAlarmList);
        }
        sysAppconfigDto.setAuditNodeCode(nodeList);
        String str1 = sysAppconfigDto.getButtonIds();
        String[] str = str1.split(",");
        List<String> klList = new ArrayList<>();
        for (String kl :
                str) {
            klList.add(kl);
        }
        sysAppconfigDto.setAppconfigButtonIds(klList);
        return sysAppconfigDto;
    }

    /**
     * 修改审核信息
     *
     * @param sysAppConfig 审核信息
     * @return 审核信息
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public int updateAppConfigEdit(SysAppConfig sysAppConfig) throws Exception {
        int ins = sysAppConfigMapper.updateAppConfigEdit(sysAppConfig);
        if (ins == 0) {
            throw new SQLException("抛出异常");
        }
        ins = sysAppConfigMapper.deleteSysAppconfigOnBy(sysAppConfig.getAppconfigId());
        if (ins == 0) {
            throw new SQLException("抛出异常");
        }
        return theNodeConfig(sysAppConfig);
    }

    /**
     * 查询节点信息
     *
     * @param appId 审核id
     * @return 审核信息
     */
    @Override
    public List<SysAppConfigNodeDto> getTheDetail(long appId) {
        List<SysAppConfigNodeDto> nodeList = sysAppConfigNodeMapper.getAppNodeInfo(appId);
        List<SysDictData> dictList = DictUtils.getDictCache("sys_of_nodes");
        Map<String, String> actualMap = dictList.stream().collect(Collectors.toMap(SysDictData::getDictValue, SysDictData::getDictLabel));
        for (SysAppConfigNodeDto sy :
                nodeList) {
            sy.setNodeTheOrderDict(actualMap.get(String.valueOf(sy.getNodeTheOrder())));
            sy.setUserAndRole(sysUserServiceImpl.selectUserNameService(sy.getNodeUserId()) + "/" + sysRoleServiceImpl.selectRoleNameService(sy.getNodeRoleId()));
        }
        return nodeList;
    }

    /**
     * 根据按钮权限码返回审核信息
     * <p>
     * ryTask.ryNoParams
     *
     * @param sysAuditHistoryVo 审核历史接受类
     * @return 1 审核完成、2 还存在下个审核、3 没权限 、4 该人员已审核
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public int getSequence(SysAuditHistoryVo sysAuditHistoryVo) throws Exception {
        // long userId = SecurityUtils.getUserId();//当前登录人(当前审核人)
        long userId = sysAuditHistoryVo.getUserId();
        String perms = sysAuditHistoryVo.getPerms();
        long buttonId = sysMenuServiceImpl.getIdByPermissionName(perms);//查询按钮id
        long appId = 0;
        int appSize = sysAppConfigMapper.countAppConfigByButtonId(buttonId);
        if (appSize == 1) {
            appId = sysAppConfigMapper.selectAppConfigByButtonId(buttonId);//查询按钮id
        } else {
            appId = sysAppConfigMapper.selectOneAppConfigByButtonId(buttonId);//查询按钮id
        }

        //根据权限码和单据号 判断是否存在审核节点
        int ins = 0;
        List<SysAppConfigNodeDto> sysList = sysAppConfigNodeMapper.getAppNodeInfo(appId);
        int jie = sysList.size();
        for (int i = 0; i < jie; i++) {
            SysAppConfigNodeDto app = sysList.get(i);
            String id1 = app.getNodeUserId();
            int pp = 0;
            int pp2 = 0;
            if (StringUtils.isEmpty(id1)) {
                pp = 1;
            }
            String[] userNode = id1.split(",");
            String id2 = app.getNodeRoleId();
            if (StringUtils.isEmpty(id2)) {
                pp2 = 1;
            }
            String[] roleIdS = id2.split(",");
            int kl = userNode.length - pp + roleIdS.length - pp2;
            String userStr = String.valueOf(userId);
            //判断是否存在相同的用户id 如果重复 返回4
            int count2 = sysAuditHistoryMapper.countAuditHistory2(app.getNodeId(), sysAuditHistoryVo.getAuditDoc(), perms, userId);
            if (count2 > 0) {
                return 4;
            }
            //判断需要的总条数
            int type = app.getNodeType();
            //需要知道现在审核在什么节点 故需要根据节点循环
            int count = sysAuditHistoryMapper.countAuditHistory(app.getNodeId(), sysAuditHistoryVo.getAuditDoc(), perms);
            sysAuditHistoryVo.setUserId(userId);
            sysAuditHistoryVo.setNodeId(app.getNodeId());
            if (type == 1) {//一人审核全通过
                if (count == 1) {//节点+1
                    continue;//不是该节点 进入下个节点循环
                } else {//就是当前节点
                    ins = whetherUserTo(userNode, userStr);
                    if (ins == 1) { //记录审核人 并存入审核历史
                        insertAuditHistory(sysAuditHistoryVo);
                        //判断是否还存在下个节点审核
                        //还需要判断存不存在下个节点
                        if (i + 1 == jie) {
                            return 1;//1人审核全通过 直接结束
                        } else {
                            return 2;
                        }
                    } else {  //用户信息没有 判断包不包含角色id
                        int bus = whetherRoleTo(roleIdS, userId);
                        if (bus == 0) {
                            return 3;//没权限 直接G
                        } else {
                            bus = insertAuditHistory(sysAuditHistoryVo); //存入审核历史
                            if (bus > 0) {
                                if (i + 1 == jie) {//1人审核全通过 直接结束
                                    return 1;
                                } else {
                                    return 2;
                                }
                            } else {
                                throw new SQLException("抛出异常");
                            }
                        }
                    }
                }
            } else {//需要全部审核
                if (count == kl) {//如果条数相等 证明节点+1
                    continue;//不是该节点 进入下个节点循环
                } else {//反之进入当前节点
                    int up = kl - count;//还需要多少审核次数可以结束
                    int in = whetherUserTo(userNode, userStr);
                    if (in > 0) {//包含
                        insertAuditHistory(sysAuditHistoryVo);//插入审核历史
                        if (up - 1 == 0) {
                            //结束当前节点 判断是否还存在下个节点
                            if (i + 1 == jie) {
                                return 1;//审核完成
                            } else {
                                return 2;
                            }
                        } else {
                            return 2;  //当前节点还存在后续审核
                        }
                    } else {//判断是否含角色信息
                        int jkl = 0;
                        jkl = whetherRoleTo(roleIdS, userId);
                        if (jkl > 0) {//包含插入
                            int klp = insertAuditHistory(sysAuditHistoryVo); //存入审核历史
                            if (klp == 0) {
                                throw new SQLException("抛出异常");
                            }
                            if (up - 1 == 0) {
                                //结束当前节点 判断是否还存在下个节点
                                if (i + 1 == jie) {
                                    return 1;//审核完成
                                } else {
                                    return 2;
                                }
                            } else {
                                return 2;  //当前节点还存在后续审核
                            }
                        } else {
                            return 3;
                        }
                    }
                }
            }
        }
        return 0;
    }

    /**
     * 根据权限码获取审核历史
     */
    @Override
    public List<SysAuditHistoryDto> getAuditHistory(SysAuditHistoryVo sysAuditHistoryVo) {
        return sysAuditHistoryMapper.getAuditHistory(sysAuditHistoryVo);
    }

    /**
     * 修改审核类型
     */
    @Override
    public int updateHistoryAppConfigEdit(SysAuditHistoryVo sysAuditHistoryVo) {
        return sysAuditHistoryMapper.updateHistoryAppConfigEdit(sysAuditHistoryVo);
    }

    /**
     * 判断是否包含用户
     */
    public int whetherUserTo(String[] userNode, String str) {
        int ins = 0;
        for (String node :
                userNode) {
            if (node.equals(str)) {//包含id
                ins = 1;
                break;
            }
        }
        return ins;
    }


    /**
     * 判断是否包含角色
     */
    public int whetherRoleTo(String[] roleIdS, long userId) {
        int ins = 0;
        List<Long> roleArr = sysRoleServiceImpl.selectRoleListByUserId(userId);
        if (StringUtils.isEmpty(roleIdS[0])) {
            return ins;
        }
        for (String ro :
                roleIdS) {
            if (roleArr.contains(Long.valueOf(ro))) {
                ins = 1;
                break;
            }
        }
        return ins;
    }


    /**
     * 新增审核历史
     */
    public int insertAuditHistory(SysAuditHistoryVo sysAuditHistoryVo) {
        return sysAuditHistoryMapper.insertAuditHistory(sysAuditHistoryVo);
    }


    /**
     * 解析新增审核信息
     */
    @Transactional(rollbackFor = Exception.class)
    public int theNodeConfig(SysAppConfig sysAppconfig) throws Exception {
        int ins = 0;
        long appId = sysAppconfig.getAppconfigId();
        JSONArray json = sysAppconfig.getAuditNodeCode();
        List<SysAppConfigNode> nodeList = JSONArray.parseArray(json.toJSONString(), SysAppConfigNode.class);
        if (nodeList.size() > 0) {
            for (SysAppConfigNode sy :
                    nodeList) {
                sy.setAppconfigId(appId);
                //走节点新增
                ins = sysAppConfigNodeMapper.insertAppconfigNode(sy);
                long jk = sy.getNodeId();
                /*JSONArray json2 = sy.getTheAlarmCode();
                List<SysTheAlarm> alarmList = JSONArray.parseArray(json2.toJSONString(), SysTheAlarm.class);
                if (alarmList.size() > 0) {
                    SysTheAlarm sys = alarmList.get(0);
                    String way = sys.getAlarmWay();
                    if (!way.equals("") && way != null) {
                        for (SysTheAlarm sysTheAlarm :
                                alarmList) {
                            sysTheAlarm.setAlarmAssociatedId(jk);
                            sysTheAlarm.setAlarmOfMaterial(5);//审核类型
                        }
                        ins = sysTheAlarmMapper.insertSysTheAlarm(alarmList);
                        if (ins == 0) {
                            throw new SQLException("抛出异常");
                        }
                    }
                }
                */
            }
        }
        return ins;
    }
}
